package hu.elte.inf.holiuml.gui;

import hu.elte.inf.holiuml.model.Attribute;
import hu.elte.inf.holiuml.model.Var;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

public class ClassAttributeOptionsDialog extends OptionsDialog{
	private JPanel propPanel;
	private JPanel editPanel;
	JTable table;
	TableModel tableModel;
	Vector<Attribute> attributes = new Vector<Attribute>();
	public ClassAttributeOptionsDialog(HoliUML parent, String title, Vector<Attribute> attributes) {
		super(parent, title);
		this.attributes = attributes;
		createPropPanel();
		fillPanels();
		setSize(new Dimension(500,260));
		setModalityType(ModalityType.APPLICATION_MODAL);
		setVisible(true);
	}
		
	private void createPropPanel(){
		propPanel = new JPanel(new BorderLayout());
		createTableModel();
		table = new JTable(tableModel, new ClassAttributeTableColumns());
		table.setPreferredSize(new Dimension(400,150));
		JComboBox visibilityCombo = new JComboBox((new Attribute()).getVisibilities());
		visibilityCombo.setSelectedIndex(0);
		JComboBox typeCombo = new JComboBox((new Var()).getTypes());
		typeCombo.setSelectedIndex(0);
		JComboBox typeModifierCombo = new JComboBox((new Var()).getTypeModifiers());
		typeModifierCombo.setSelectedIndex(1);
		table.getColumn("Visibility").setCellEditor(new DefaultCellEditor(visibilityCombo));
		table.getColumn("Type").setCellEditor(new DefaultCellEditor(typeCombo));
		table.getColumn("TypeModifier").setCellEditor(new DefaultCellEditor(typeModifierCombo));
		(table.getTableHeader()).setReorderingAllowed(false);
		table.getColumn("Name").setCellEditor(new DefaultCellEditor(new JTextField()));
		table.getColumn("Description").setCellEditor(new DefaultCellEditor(new JTextField()));
		JScrollPane scrollPane = new JScrollPane(table);
		scrollPane.setPreferredSize(new Dimension(400,150));
		JButton addButton = new JButton("Add New");
		addButton.addActionListener(addAttributeAction);
		JButton deleteButton = new JButton("Delete Selected");
		deleteButton.addActionListener(deleteAttributeAction);
		editPanel = new JPanel(new GridLayout(1,2));
		editPanel.add(addButton);
		editPanel.add(deleteButton);
		propPanel.add("Center", scrollPane);
		propPanel.add("South", editPanel);
	}

	private void fillPanels(){
		getContentPane().setLayout(new BorderLayout());
		getContentPane().add("North", propPanel);
		getContentPane().add("South", buttonPanel);
	}
	
	protected void createTableModel(){
		tableModel = new AbstractTableModel(){
	          public int getColumnCount() { return 5; }
	          public int getRowCount() { return attributes.size();}
	          public boolean isCellEditable(int col, int row){
	        	  return true;
	          }
	          // visibility, name, type, description
	          public Object getValueAt(int row, int col) {
	        	  Attribute attr = attributes.get(row);
	        	  switch(col){
	        	  	case 0 : return attr.getVisibility();
	        	  	case 1 : return attr.getName();
	        	  	case 2 : return attr.getType();
	        	  	case 3 : return attr.getTypeModifyer();
	        	  	case 4 : return attr.getDescription();
	        	  }
	        	  return null;
	          }
	          public void setValueAt(Object value, int row, int col) {
	        	  switch(col){
	        	  	case 0 : attributes.get(row).setVisibility(Attribute.Visibility.valueOf(value.toString()));break;
	        	  	case 1 : attributes.get(row).setName((String)value);break;
	        	  	case 2 : attributes.get(row).setType(Var.VarType.valueOf(value.toString()));break;
	        	  	case 3 : attributes.get(row).setTypeModifyer(Var.TypeModifyer.valueOf(value.toString()));break;
	        	  	case 4 : attributes.get(row).setDescription((String)value);break;
	        	  	default : break;
	        	  }
	        	  fireTableDataChanged();
	          }
		};
	}
	
	private ActionListener addAttributeAction = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			Attribute newAttribute = new Attribute();
			newAttribute.setName("");
			newAttribute.setType(Var.VarType.INT);
			newAttribute.setDescription("");
			newAttribute.setTypeModifyer(Var.TypeModifyer.NOTHING);
			attributes.add(newAttribute);
			if(attributes.size()*16 > 150){
				table.setPreferredSize(new Dimension(250, attributes.size()*16));
			}
			((AbstractTableModel)tableModel).fireTableChanged(null);
		}
	};
	
	private ActionListener deleteAttributeAction = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			int indexOfSelected = table.getSelectedRow();
			if(indexOfSelected != -1){
				table.editingStopped(null);
				attributes.remove(indexOfSelected);
				if(attributes.size()*16 > 150){
					table.setPreferredSize(new Dimension(250, attributes.size()*16));
				}
				((AbstractTableModel)tableModel).fireTableChanged(null);
			}
		}
	};
	
	@Override
	protected void processCancel() {
		// TODO Auto-generated method stub
		
	}

	@Override
	protected boolean processOK() {
		table.editingStopped(null);
		boolean missingValues = false;
		for(int i = 0; i < attributes.size(); i++){
			String name = attributes.get(i).getName().replaceAll(" ", "");
			missingValues = (name.equals("")) || missingValues;
		}
		if(missingValues){
			JOptionPane.showMessageDialog(super.parent, "There are missing attribute names, please fill in or remove these elements!");
			return false;
		}else{
			return true;
		}
	}
	
	public Vector<Attribute> getAttributes(){
		return attributes;
	}
	
	private ActionListener addNewRowAction = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			
		}
	};
	
	private class ClassAttributeTableColumns extends DefaultTableColumnModel{
		private TableColumn[] tempTableColumns = {
			new TableColumn(0, 80),
			new TableColumn(1, 80),
			new TableColumn(2, 80),
			new TableColumn(3, 80),
			new TableColumn(4, 80)
		};
		
		public ClassAttributeTableColumns(){
			tempTableColumns[0].setHeaderValue("Visibility");
			tempTableColumns[1].setHeaderValue("Name");
			tempTableColumns[2].setHeaderValue("Type");
			tempTableColumns[3].setHeaderValue("TypeModifier");
			tempTableColumns[4].setHeaderValue("Description");
			for(int i= 0; i < 5; i++){
				tableColumns.add(tempTableColumns[i]);
			}
		}
		public int getColumnCount(){
			return tempTableColumns.length;
			
		}
	}
}
